package br.com.uniban.action;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

import br.com.uniban.bo.ProvaBO;
import br.com.uniban.dto.ProvaDTO;
import br.com.uniban.entity.Disciplina;
import br.com.uniban.entity.Prova;
import br.com.uniban.entity.ProvaQuestao;
import br.com.uniban.entity.ProvaQuestoesRespondidas;
import br.com.uniban.entity.ProvaRespondida;
import br.com.uniban.entity.QuestoesAvulsas;
import br.com.uniban.entity.Usuario;
import br.com.uniban.form.ProvaForm;

import com.google.gson.Gson;


public class ProvaAction extends DispatchAction {

	private ProvaBO bo = null;
	private static final String FAZER_PROVA = "fazerProva";
	private static final String VER_PROVA = "verProva";
	private static final String CADASTRAR_PROVA = "cadastrarProva";
	private static final String INICIO_FAZER_PROVA = "inicioProva";
	private static final String VER_PROVA_RESP = "verProvaResp";


	public ProvaAction() {
		try {
			if (bo == null)
				bo = new ProvaBO();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public ActionForward inicio(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)throws Exception {

		ProvaForm form = (ProvaForm) actionForm;
		List<Disciplina> listaDisciplina = (List<Disciplina>) request.getSession().getAttribute(UsuarioAction.LISTA_DISCIPLINA);
		if(listaDisciplina == null){
			response.setStatus(response.SC_BAD_REQUEST);
			return null;
		}
		form.setListaDisciplina(listaDisciplina);
		return mapping.findForward(CADASTRAR_PROVA);

	}
	
	public ActionForward fazerProvaInicio(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)throws Exception {

		ProvaForm form = (ProvaForm) actionForm;
		List<Disciplina> listaDisciplina = (List<Disciplina>) request.getSession().getAttribute(UsuarioAction.LISTA_DISCIPLINA);
		form.setListaDisciplina(listaDisciplina);
		resetListaProva(mapping, actionForm, request, response);
		return mapping.findForward(INICIO_FAZER_PROVA);

	}

	public ActionForward cadastrarProva(ActionMapping mapping,ActionForm actionForm, 
			HttpServletRequest request,HttpServletResponse response) throws Exception {

		ProvaForm form = (ProvaForm) actionForm;
		Prova prova = form.getProva();
		prova.setUsuario(UsuarioAction.getUsuario(request));
		bo.cadastraProva(prova,form.getListaQuestoes());
		return null;
	}

	public ActionForward cadastrarProvaResp(ActionMapping mapping,ActionForm actionForm, 
			HttpServletRequest request,HttpServletResponse response) throws Exception {

		ProvaForm form = (ProvaForm) actionForm;
		bo.cadastraProvaRespondida(form.getProvaResp());

		return null;
	}

	public ActionForward listarProvas(ActionMapping mapping,ActionForm actionForm, 
			HttpServletRequest request,HttpServletResponse response) throws Exception {

		ProvaForm form = (ProvaForm) actionForm;
		ProvaDTO dto = form.getFiltro();
		dto.setIdCriador(UsuarioAction.getUsuario(request).getId());
		
		List<Prova> lista = bo.listaProva(dto);

		for (Prova prova : lista) {
			prova.setProvaResp(null);
			for (ProvaQuestao provaQuestao : prova.getListaDeQuestoes()) {				
				provaQuestao.setProva(null);
				provaQuestao.setQuestao(null);
			}
		}		
		Gson gson = new Gson();
		response.setContentType("application/json");
		String json = gson.toJson(lista);
		response.getWriter().write(json);
		return null;
	}


	public ActionForward listarProvasCriadas(ActionMapping mapping,ActionForm actionForm, 
			HttpServletRequest request,HttpServletResponse response) throws Exception {

		ProvaForm form = (ProvaForm) actionForm;
		Long idCriador = UsuarioAction.getUsuario(request).getId();
		List<Prova> listaProva = bo.listaMinhasProva(idCriador);
		Map<Integer, Prova> map = new HashMap<Integer, Prova>();
		for (Prova prova : listaProva) {
			prova.setProvaResp(null);
			map.put(prova.getId(), prova);
			for (ProvaQuestao provaQuestao : prova.getListaDeQuestoes()) {
				provaQuestao.setProva(null);
				provaQuestao.setQuestao(null);
			}
			if(prova.getProvaResp() != null)
				prova.getProvaResp().setProva(null);
		}
		form.setListaProva(map);
		
		Gson gson = new Gson();
		String json = gson.toJson(listaProva);
		response.setContentType("application/json");
		response.getWriter().write(json);
		
		return null;
	}

	public ActionForward listarProvasFeitas(ActionMapping mapping,ActionForm actionForm, 
			HttpServletRequest request,HttpServletResponse response) throws Exception {

		ProvaForm form = (ProvaForm) actionForm;

		return null;
	}
	
	public ActionForward verProvaResp(ActionMapping mapping,ActionForm actionForm, 
			HttpServletRequest request,HttpServletResponse response) throws Exception {

		ProvaForm form = (ProvaForm) actionForm;
		Integer idProvaResp = Integer.parseInt(request.getParameter("idProvaResp"));
		ProvaRespondida provaRespondida = bo.getProvaResp(idProvaResp);
		provaRespondida = formataProvaResp(provaRespondida);
		form.setProvaResp(provaRespondida);
		
		return mapping.findForward(VER_PROVA_RESP);
	}

	public ActionForward listaQuestao(ActionMapping mapping,ActionForm actionForm, 
			HttpServletRequest request,HttpServletResponse response) throws Exception {

		ProvaForm form = (ProvaForm) actionForm;
		List<QuestoesAvulsas> listaQuestao = form.getListaQuestoes();
		List<Disciplina> listaDisciplinas = form.getListaDisciplina();
		if (listaQuestao != null && !listaQuestao.isEmpty()) {

			for (int k = 0; k < listaQuestao.size();k++) {
				for (Disciplina disciplina : listaDisciplinas) {
					QuestoesAvulsas questao = listaQuestao.get(k);
					if (disciplina.getId().equals(questao.getDisciplina().getId())) {
						questao.getDisciplina().setNome(disciplina.getNome());
						listaQuestao.set(k,questao);
						break;
					}
				}
			}

			Gson gson = new Gson();
			response.setContentType("application/json");
			String json = gson.toJson(listaQuestao);
			response.getWriter().write(json);

		}

		return null;
	}

	public ActionForward gabarito(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		Integer idProva = Integer.parseInt(request.getParameter("idProva"));
		String json = bo.gabarito(idProva);
		response.setContentType("application/json");
		response.getWriter().write(json);

		return null;
	}

	public ActionForward fazerProva(ActionMapping mapping,ActionForm actionForm, 
			HttpServletRequest request,HttpServletResponse response) throws Exception {

		ProvaForm form = (ProvaForm) actionForm;
		Integer idProva = Integer.parseInt(request.getParameter("idProva"));
		Prova prova = bo.getProva(idProva);
		Integer tam = prova.getListaDeQuestoes().size();
		
		List<ProvaQuestoesRespondidas> listaQuestaoResp = formataQuestaoResp(tam);
		
		prova = formataProva(prova);
		
		Usuario usuario = UsuarioAction.getUsuario(request);
		ProvaRespondida provaResp = new ProvaRespondida(prova, usuario, new Date(), listaQuestaoResp);
		form.setProvaResp(provaResp);
		
		request.setAttribute("Prova", prova);

		return mapping.findForward(FAZER_PROVA);
	}
	

	public ActionForward verProva(ActionMapping mapping,ActionForm actionForm, 
			HttpServletRequest request,HttpServletResponse response) throws Exception {

		Integer idProva = Integer.parseInt(request.getParameter("idProva"));
		Prova prova = bo.getProva(idProva);		
		prova = formataProva(prova);
		request.setAttribute("Prova", prova);

		return mapping.findForward(VER_PROVA);
	}


	public ActionForward adicionarQuestao(ActionMapping mapping,ActionForm actionForm, 
			HttpServletRequest request,HttpServletResponse response) throws Exception {

		ProvaForm form = (ProvaForm) actionForm;
		form.getQuestao().setUsuario(UsuarioAction.getUsuario(request));

		if (form.getListaQuestoes() == null)
			//form.getProva().setListaDeQuestoes(new ArrayList<QuestoesAvulsas>());
			form.setListaQuestoes(new ArrayList<QuestoesAvulsas>());
		form.getListaQuestoes().add(form.getQuestao());
		form.resetQuestao();
		
		return null;
	}

	public ActionForward deletarQuestao(ActionMapping mapping,ActionForm actionForm, 
			HttpServletRequest request,HttpServletResponse response) throws Exception {

		ProvaForm form = (ProvaForm) actionForm;
		int indice = Integer.parseInt(request.getParameter("indice"));
		form.getListaQuestoes().remove(indice);

		return null;
	}

	public ActionForward editarQuestao(ActionMapping mapping,ActionForm actionForm, 
			HttpServletRequest request,HttpServletResponse response) throws Exception {

		ProvaForm form = (ProvaForm) actionForm;
		int indice = Integer.parseInt(request.getParameter("indice"));
		QuestoesAvulsas questaoNova = form.getQuestao();
		QuestoesAvulsas questaoAntiga = form.getListaQuestoes().get(indice);
		Boolean isIgual = isQuestaoIgual(questaoNova, questaoAntiga);
		Boolean retorno = false;
		if (!isIgual) {
			if (questaoNova.getId() != 0){
				questaoNova.setId(null);
				retorno = true;
			}
			form.getListaQuestoes().set(indice, questaoNova);
		}
		form.resetQuestao();
		response.getWriter().write(retorno.toString());
		return null;
	}
	
	private Prova formataProva(Prova prova) {
		String quebraDeLinha = "\n";  
		String br = "<br/>";
		Integer tam = prova.getListaDeQuestoes().size();
		for (int i = 0; i < tam; i++) {
			
			QuestoesAvulsas questao = prova.getListaDeQuestoes().get(i).getQuestao();
			questao.setAlternativa_A(StringEscapeUtils.escapeHtml4(questao.getAlternativa_A().replaceAll(quebraDeLinha, br)).replace("&lt;br/&gt;", "<br/>"));
			questao.setAlternativa_B(StringEscapeUtils.escapeHtml4(questao.getAlternativa_B().replaceAll(quebraDeLinha, br)).replace("&lt;br/&gt;", "<br/>"));
			questao.setAlternativa_C(StringEscapeUtils.escapeHtml4(questao.getAlternativa_C().replaceAll(quebraDeLinha, br)).replace("&lt;br/&gt;", "<br/>"));
			questao.setAlternativa_D(StringEscapeUtils.escapeHtml4(questao.getAlternativa_D().replaceAll(quebraDeLinha, br)).replace("&lt;br/&gt;", "<br/>"));
			questao.setPergunta(StringEscapeUtils.escapeHtml4(questao.getPergunta().replaceAll(quebraDeLinha, br)).replace("&lt;br/&gt;", "<br/>"));
			}
		
		return prova;
	}
	
	private ProvaRespondida formataProvaResp(ProvaRespondida provaRespondida) {
		String quebraDeLinha = "\n";  
		String br = "<br/>";
		Integer tam = provaRespondida.getListQuestoesRespondida().size();
		for (int i = 0; i < tam; i++) {
			
			QuestoesAvulsas questao = provaRespondida.getListQuestoesRespondida().get(i).getQuestoesAvulsas();
			questao.setAlternativa_A(StringEscapeUtils.escapeHtml4(questao.getAlternativa_A().replaceAll(quebraDeLinha, br)).replace("&lt;br/&gt;", "<br/>"));
			questao.setAlternativa_B(StringEscapeUtils.escapeHtml4(questao.getAlternativa_B().replaceAll(quebraDeLinha, br)).replace("&lt;br/&gt;", "<br/>"));
			questao.setAlternativa_C(StringEscapeUtils.escapeHtml4(questao.getAlternativa_C().replaceAll(quebraDeLinha, br)).replace("&lt;br/&gt;", "<br/>"));
			questao.setAlternativa_D(StringEscapeUtils.escapeHtml4(questao.getAlternativa_D().replaceAll(quebraDeLinha, br)).replace("&lt;br/&gt;", "<br/>"));
			questao.setPergunta(StringEscapeUtils.escapeHtml4(questao.getPergunta().replaceAll(quebraDeLinha, br)).replace("&lt;br/&gt;", "<br/>"));
			}
		
		return provaRespondida;
	}
	
	private List<ProvaQuestoesRespondidas> formataQuestaoResp(Integer tam) {
		List<ProvaQuestoesRespondidas> listaQuestaoResp = new ArrayList<ProvaQuestoesRespondidas>(tam);
		for (int i = 0; i < tam; i++) 
			listaQuestaoResp.add(new ProvaQuestoesRespondidas());
		
		return listaQuestaoResp;
	}

	private boolean isQuestaoIgual(QuestoesAvulsas nova, QuestoesAvulsas antiga) {

		if (!nova.getAlternativa_A().trim().equalsIgnoreCase(antiga.getAlternativa_A().trim())) {
			return false;
		
		} else if (!nova.getAlternativa_B().trim().equalsIgnoreCase(antiga.getAlternativa_B().trim())) {
			return false;
		
		} else if (!nova.getAlternativa_C().trim().equalsIgnoreCase(antiga.getAlternativa_C().trim())) {
			return false;
		
		} else if (!nova.getAlternativa_D().trim().equalsIgnoreCase(antiga.getAlternativa_D().trim())) {
			return false;
		
		} else if (!nova.getPergunta().trim().equalsIgnoreCase(antiga.getPergunta().trim())) {
			return false;
		
		} else if (!nova.getResposta().equals(antiga.getResposta())) {
			return false;
		
		} else if (!nova.getDisciplina().equals(antiga.getDisciplina())) {
			return false;
		
		} else if (nova.getListaDePalavrasChaves() != null && antiga.getListaDePalavrasChaves() != null && 
				  !nova.getListaDePalavrasChaves().toString().trim().equalsIgnoreCase(antiga.getListaDePalavrasChaves().toString().trim())) {
			return false;
		}else if(nova.getListaDePalavrasChaves() == null && antiga.getListaDePalavrasChaves() != null || 
				 antiga.getListaDePalavrasChaves() == null && nova.getListaDePalavrasChaves() != null){
			return false;
		}
		return true;
	}

	public ActionForward resetListaQuestao(ActionMapping mapping,ActionForm actionForm, 
			HttpServletRequest request,HttpServletResponse response) throws Exception {
		ProvaForm form = (ProvaForm) actionForm;
		if (form.getListaQuestoes() != null)
			form.getListaQuestoes().clear();
		form.resetProva();
		return null;
	}
	
	public ActionForward resetListaProva(ActionMapping mapping,ActionForm actionForm, 
			HttpServletRequest request,HttpServletResponse response) throws Exception {
		ProvaForm form = (ProvaForm) actionForm;
		if (form.getListaProva() != null)
			form.getListaProva().clear();
		return null;
	}
}
